#include "kernel.h"

extern void shell_command_run();
/*
 * 
 * Handles the keyboard interrupt
 *
 * The following is the keyboard to scancode mapping
 *
 *  Reference: http://www.win.tue.nl/~aeb/linux/kbd/scancodes-1.html
 *
 */
void keyboard_handler(void)
{
    unsigned char kbdus[128] =
    {
       0,  /* Error code */
       27, /* Esc key */ 
      '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b',
      '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n',
       0,  /* Enter key */
      'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', 
      '`',   
       0,  /* Left shift */
      '\\', 
      'z', 'x', 'c', 'v', 'b', 'n',  'm', ',', '.', '/',   
       0, /* Right shift */
      '*',
       0, /* Left alt key */
      ' ',
       0, /* Caps lock key */
       0, 0, 0, 0, 0, 0, 0, 0, 0, 0, /* F1 to F10 keys */
       0, /* Num lock */
       0, /* Scroll lock */
       0, /* Home */
       0, /* Up arrow */
       0, /* Page up key */
      '-',
       0, /* Left arrow */
       0,
       0, /* Right arrow */
      '+',
       0, /* End key */
       0, /* Down arrow */
       0, /* Page down key */
       0, /* Insert key */
       0, /* Delete key */
       0, 0, 0, /* some other keys specific to keyboards */
       0,
       0,
       0,
    };

    /*
     *
     * Read from the keyboard's data buffer
     *
     */
    scancode = inb(0x60);

    /*
     *
     * If the top bit of the byte we read from the keyboard is
     *  set, that means that a key has just been released
     *
     */
    if (scancode & 0x80)
    {
	
        /*
         *
         * You can use this one to see if the user released the
         *  shift, alt, or control keys...
         *
         */
    }
    else
    {
        /*
         *
         * Here, a key was just pressed. Please note that if you
         *  hold a key down, you will get repeated key press
         *  interrupts. 
         *
         * Just to show you how this works, we simply translate
         *  the keyboard scancode into an ASCII value, and then
         *  display it to the screen. You can get creative and
         *  use some flags to see if a shift is pressed and use a
         *  different layout, or you can add another 128 entries
         *  to the above layout to correspond to 'shift' being
         *  held. If shift is held using the larger lookup table,
         *  you would add 128 to the scancode when you look for it 
         *
         */
	
	cmd[cmditer ++] = kbdus[scancode];
	printc(kbdus[scancode]);
	
	char_num += 2;
	if (kbdus[scancode] == '\n' || char_num == 160) 
	{
	      cmditer = 0;
	      shell_command_run(cmd);
	}
    }


}

/*
 * 
 * Installs the keyboard handler into IRQ1
 *
 */
void keyboard_install()
{
    irq_install_handler(1, (void *)keyboard_handler);
}
